package tictactoe;

public class Game {
	public Game(GameStatus g) {
		gamelogic = new GameLogic(g);
		ai = new AI();
		ai_difficulty = 0;
		show_threats = true;
		single_player = true;
	}
	
	public void newGame() {
		gamelogic.reset();
	}
	
	public void undo() {
		gamelogic.undo();
	}
	
	public void redo() {
		gamelogic.redo();
	}
	
	public boolean getXTurn() {
		return gamelogic.get_x_turn();
	}
	
	public void makeMove(int w, int x, int y, int z) {
		System.out.print("human move\n");
		if(gamelogic.makeMove(w,x,y,z)) {
			System.out.print("Ai move\n");
                        if(gamelogic.winState()==GameStatus.InProgressSingle){
                            int[] move = ai.move(gamelogic.gameState(), gamelogic.get_x_turn(), ai_difficulty);
                            gamelogic.makeMove(move[0],move[1],move[2],move[3]);
                        }
                }
	}
	
	public SquareColor[][][][] update() {
		Marker[][][][] board = gamelogic.gameState();
		int board_length = gamelogic.getLength();
		SquareColor[][][][] displayboard = new SquareColor[board_length][board_length][board_length][board_length];
		for(int coord1 = 0; coord1 < board_length; coord1++) {
			for(int coord2 = 0; coord2 < board_length; coord2++) {
				for(int coord3 = 0; coord3 < board_length; coord3++) {
					for(int coord4 = 0; coord4 < board_length; coord4++) {
						if(board[coord1][coord2][coord3][coord4] == Marker.X) {
							displayboard[coord1][coord2][coord3][coord4] = SquareColor.X;
						}
						if(board[coord1][coord2][coord3][coord4] == Marker.O) {
							displayboard[coord1][coord2][coord3][coord4] = SquareColor.O;
						}
						if(board[coord1][coord2][coord3][coord4] == Marker.Empty) {
							displayboard[coord1][coord2][coord3][coord4] = SquareColor.Empty;
						}
					}
				}
			}
		}

		if(show_threats) {
		//Look for threats
			
			//dim# specifies what each dimension is doing while checking for rows.
			//Each dimension in a winning board has to either be fixed, increasing or decreasing
			//Numbers >= 0 are treated as fixed coordinates whose value is the same as their dimension
			//-1 represents a coordinate that is increasing, -2 represents a coordinate that is decreasing
			Row row = new Row();
			do {
				int x_count = 0;
				int o_count = 0;
				for(int itr = 0; itr < board_length; itr++) {
					Square s = row.getSquare(itr, board_length);
					if(board[s.coord1][s.coord2][s.coord3][s.coord4] == Marker.X) {
						x_count++;
					}
					if(board[s.coord1][s.coord2][s.coord3][s.coord4] == Marker.O) {
						o_count++;
					}
				}
				if(x_count == 3 && o_count == 0) {
					for(int itr = 0; itr < board_length; itr++) {	
						Square s = row.getSquare(itr, board_length);
						if(displayboard[s.coord1][s.coord2][s.coord3][s.coord4] == SquareColor.Othreat) {
							displayboard[s.coord1][s.coord2][s.coord3][s.coord4] = SquareColor.Boththreat;
						}
						else if(displayboard[s.coord1][s.coord2][s.coord3][s.coord4] == SquareColor.Empty) {
							displayboard[s.coord1][s.coord2][s.coord3][s.coord4] = SquareColor.Xthreat;
						}
					}
				}
				if(o_count == 3 && x_count == 0) {
					for(int itr = 0; itr < board_length; itr++) {	
						Square s = row.getSquare(itr, board_length);
						if(displayboard[s.coord1][s.coord2][s.coord3][s.coord4] == SquareColor.Xthreat) {
							displayboard[s.coord1][s.coord2][s.coord3][s.coord4] = SquareColor.Boththreat;
						}
						else if(displayboard[s.coord1][s.coord2][s.coord3][s.coord4] == SquareColor.Empty) {
							displayboard[s.coord1][s.coord2][s.coord3][s.coord4] = SquareColor.Othreat;
						}
					}
				}
				
			} while(row.next(board_length));
		}
		return displayboard;
	}
	
	public MarkedSquare[][] getDiagonals() {
		int board_length = gamelogic.getLength();
		int num_dimensions = 4;
		MarkedSquare[][] Diagonals = new MarkedSquare[72][4];
		int index = 0;
		Row r = new Row();
		Marker[][][][] board = gamelogic.gameState();
		do {
			for(int sqnum = 0; sqnum < num_dimensions; sqnum++) {
				Square square = r.getSquare(sqnum, board_length);
				Marker marker = board[square.coord1][square.coord2][square.coord3][square.coord4];
				Diagonals[index][sqnum] = new MarkedSquare(square.coord1,
						square.coord2,square.coord3,square.coord4,marker);
			}
			index++;
		} while(r.nextNonPlanar(board_length));
		return Diagonals;
		
	}
	
	public void setShowThreats(boolean threatval) {
		show_threats = threatval;
	}
	
	public GameStatus winState() {
		return gamelogic.winState();
	}
	
	public void setAiDifficulty(int difficulty) {
		if(difficulty <=0 || difficulty > 3) return;
		ai_difficulty = difficulty;
	}
	
	
	
	GameLogic gamelogic;
	AI ai;
	boolean show_threats;
	boolean single_player;
	int ai_difficulty;
}
